#coding=utf-8
# 针对 cifar10, Lenet-5结构，采用TF2.0的建模方式方法, 3个卷积层
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1'

import tensorflow as tf
import numpy as np
from tensorflow import keras
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix


model = keras.models.load_model('./data/course9_1_model.h5', compile=False) ##重建完整模型，但不重建，False只能predict， True可以evaluate
model.summary()

# 数据预处理函数
def preprocess(x, y):
    x = tf.cast(x, dtype=tf.float32) / 255.
    return x, y

# 加载数据集
np.random.seed(2021)  # 固定随机因子
_, (x_test, y_test) = tf.keras.datasets.cifar10.load_data()

# 构建数据集并设置分批
# train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train))
# train_db = train_db.batch(1000)
# train_db = train_db.map(preprocess)

test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test))
test_db = test_db.batch(100)
test_db = test_db.map(preprocess)

# 测试

# model.evaluate(test_db)
y_pred = model.predict(test_db)

print(y_pred.shape, y_test.shape)

acc = keras.metrics.SparseCategoricalAccuracy()(y_test, y_pred)
print(acc)

# 计算混淆矩阵并绘制########
def plotcm(cm):
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
    classes = [str(i) for i in range(10)]
    labels = range(10)
    plt.matshow(cm, cmap=plt.cm.Blues)
    plt.title('混淆矩阵')
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes)
    plt.yticks(tick_marks, classes)
    for x in range(len(cm)):
        for y in range(len(cm)):
            plt.annotate(cm[x, y], xy=(x, y),
                         horizontalalignment='center',
                         verticalalignment='center')
    plt.grid(True, which='minor', linestyle='-')

y_pred = tf.argmax(y_pred, 1).numpy()
cm = confusion_matrix(y_test, y_pred)  # 混淆矩阵
print(cm)
plotcm(cm)      # 绘制混淆矩阵
##

print(y_test.dtype, y_pred.dtype)


# 绘制错分的 图里
y_pred = np.reshape(y_pred, (-1, 1))  # 变回 （10000,1)与y_test同型
ins = y_test != y_pred
diff_index = np.where(ins == True)[0]  # 查找不相同的下标

labels = ['飞机', '汽车', '鸟类', '猫', '鹿', '狗', '蛙类', '马', '船', '卡车']
numForPaint = 16
plt.figure()
for i in range(numForPaint): #只显示前16个
    j = diff_index[i]
    img = x_test[j]         # 取出图片

    plt.subplot(2, 8, i+1, xticks=[], yticks=[])                   # 8*2子图显示
    plt.imshow(img)

    ii = y_test[j][0]
    jj = y_pred[j][0]

    plt.title(f'{labels[ii]}--> {labels[jj]}', fontproperties='SimHei')   # 显示标题
    # plt.title(f'{y_test[j]}--> {y_pred[j]}')   # 显示标题
    plt.subplots_adjust(wspace=0.1, hspace=0.2)#

plt.show()


# 绘制错分的 图里
y_pred = np.reshape(y_pred, (-1, 1))
ins = y_test != y_pred

diff_index = np.where(ins == True)[0]  # 查找不相同的下标
numForPaint = 16
plt.figure()
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负
lables = ['飞机', '汽车', '鸟类', '猫', '鹿', '狗', '蛙类', '马', '船', '卡车']
for i in range(numForPaint): #只显示前16个
    j = diff_index[i]
    img = x_test[j]         # 取出图片
    # input(img.shape)

    plt.subplot(2, 8, i+1, xticks=[], yticks=[])                   # 8*2子图显示
    # plt.imshow(img, cmap='Greys')              # 黑白显示
    plt.imshow(img)              # 黑白显示

    y_t = y_test[j][0]
    y_p = y_pred[j][0]
    plt.title(f'{lables[y_t]}--> {lables[y_p]}', fontproperties='SimHei')   # 显示标题
    # plt.title(f'{y_test[j]}--> {y_pred[j]}')   # 显示标题, 如果不支持中文，请注释上面代码
    plt.subplots_adjust(wspace=0.1, hspace=0.2)#

plt.show()



